﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using NUnit.Framework;

using NUnitResults;

namespace NUnitResultsTests.Unit
{
    /// <summary>
    /// Tests the TestCaseCount class.
    /// </summary>
    public class TestCaseCountTests
    {
        #region Total

        /// <summary>
        /// Test construction and the Total property.
        /// </summary>
        /// <param name="counts"></param>
        /// <returns></returns>
        [Test, TestCaseSource("GetTestTotalTestCases")]
        public Int32 TestTotal(IDictionary<Status, Int32> counts)
        {
            var tcc = new TestCaseCount(counts);
            return tcc.Total;
        }

        /// <summary>
        /// Provides test case for the TestTotal method.
        /// </summary>
        /// <returns></returns>
        private IEnumerable<TestCaseData> GetTestTotalTestCases()
        {
            yield return new TestCaseData(null).Throws(typeof(ArgumentNullException));
            yield return new TestCaseData(new Dictionary<Status, Int32> { { Status.Success, 1 } }).Returns(1);
            yield return new TestCaseData(new Dictionary<Status, Int32> { { Status.Success, 1 }, { Status.Inconclusive, 1 } }).Returns(2);
            yield return new TestCaseData(new Dictionary<Status, Int32> { { Status.Success, 1055 }, { Status.Inconclusive, 127 }, {Status.NonRunnable, 54 } }).Returns(1236);
        }

        #endregion

        #region FromCases

        /// <summary>
        /// Tests the Total property for TestCaseCounts produced via
        /// FromCases, and checks that each instance returned from
        /// FromCases contains every Status enumeration member in
        /// correct order.
        /// </summary>
        /// <param name="results"></param>
        /// <returns></returns>
        [Test, TestCaseSource("GetTestFromCasesTestCases")]
        public Int32 TestFromCases(IList<ITestResult> cases)
        {
            var tcc = TestCaseCount.FromCases(cases);

            using (var e = tcc.GetEnumerator())
            {
                Assert.IsTrue(e.MoveNext());
                Assert.AreEqual(Status.Success, e.Current.Key);
                Assert.IsTrue(e.MoveNext());
                Assert.AreEqual(Status.Ignored, e.Current.Key);
                Assert.IsTrue(e.MoveNext());
                Assert.AreEqual(Status.Inconclusive, e.Current.Key);
                Assert.IsTrue(e.MoveNext());
                Assert.AreEqual(Status.NonRunnable, e.Current.Key);
                Assert.IsTrue(e.MoveNext());
                Assert.AreEqual(Status.Failed, e.Current.Key);
                Assert.IsTrue(e.MoveNext());
                Assert.AreEqual(Status.Error, e.Current.Key);
                Assert.IsTrue(e.MoveNext());
                Assert.AreEqual(Status.Unrecognised, e.Current.Key);
            }

            return tcc.Total;
        }

        /// <summary>
        /// Gets test case data for the TestFromCases test.
        /// </summary>
        /// <returns></returns>
        private IEnumerable<TestCaseData> GetTestFromCasesTestCases()
        {
            yield return new TestCaseData(null).Throws(typeof(ArgumentNullException));
            yield return new TestCaseData(new List<ITestResult> { new TestCase("", "", Status.Success, null, null) }).Returns(1);
            yield return new TestCaseData(new List<ITestResult> { new TestCase("", "", Status.Success, null, null), new TestCase("", "", Status.Success, null, null) }).Returns(2);
            yield return new TestCaseData(new List<ITestResult> { new TestCase("", "", Status.Success, null, null), new TestCase("", "", Status.Failed, null, null) }).Returns(2);
            yield return new TestCaseData(new List<ITestResult> 
            { 
                new TestCase("", "", Status.Ignored, null, null), 
                new TestSuite("", "", Status.Failed, SuiteType.TestFixture, null, null, new List<ITestResult> 
                { 
                    new TestCase("", "", Status.Success, null, null), 
                    new TestCase("", "", Status.Failed, null, null) 
                }) 
            }).Returns(3);
        }

        #endregion
    }
}
